home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
tppop16.zip
/
WINDOWS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-09-28
|
7KB
|
218 lines
{$R-,S-,I+,D+,T+,F-,V-,B-,N-,L+ }
Unit Windows;
Interface
Uses Crt;
Type
BorderType = (None,Single,Double,DoubleTop,DoubleSide,Solid);
Var
VideoMode : Byte Absolute $0000:$0449; { current video mode }
Procedure DrawBox(X1,Y1,X2,Y2,Forground,Background : Word;
Border : BorderType);
Procedure MakeWindow(X1,Y1,X2,Y2,Forground,BackGround : Word;
Border : BorderType);
Procedure RemoveWindow;
Procedure SetCursor(Cursor : Word);
InLine($59/ { pop cx }
$B4/$01/ { mov ah,1 }
$CD/$10); { int 10h }
Implementation
Type
ScreenType = Array[1..2000] of Word;
ScreenPtr = ^ScreenRecord;
ScreenRecord = Record
Screen : ScreenType; { holds the screen memory }
UpperCors : Word; { holds window coordinates }
LowerCors : Word; { holds window coordinates }
OldAttr : Word; { holds character attribute }
XY : Word; { holds the cursor position }
Cursor : Word; { holds the cursor shape }
Previous : ScreenPtr; { pointer to underlying window }
End;
Var
MonoScreen : ScreenType Absolute $B000:0000; { monochome screen }
ColorScreen : ScreenType Absolute $B800:0000; { CGA screen }
CurrentScreen : ScreenPtr; { place to save screen info }
ScreenSaved : Boolean; { Are any windows on the heap? }
Procedure GotoXYAbs(XY : Word);
InLine($5A/ { pop dx }
$B4/$02/ { mov ah,2 }
$30/$FF/ { xor bh,bh }
$CD/$10); { int 10h }
Function WhereXYAbs : Word;
InLine($B4/$03/ { mov ah,3 }
$30/$FF/ { xor bh,bh }
$CD/$10/ { int 10h }
$89/$D0); { mov ax,dx }
Function CursorShape : Word;
InLine($B4/$03/ { mov ah,3 }
$30/$FF/ { xor bh,bh }
$89/$C8); { mov ax,cx }
Procedure SaveScreen;
{ saves the screen memory, window coordinates, }
{ cursor position, and character attribute. }
Var
NewScreen : ScreenPtr;
Begin
New(NewScreen);
With NewScreen^ Do
Begin
If ScreenSaved
Then Previous := CurrentScreen
Else Previous := Nil;
ScreenSaved := True;
If VideoMode = 7 { save the screen memory }
Then Screen := MonoScreen
Else Screen := ColorScreen;
UpperCors := WindMin; { save the window coordinates }
LowerCors := WindMax;
OldAttr := TextAttr; { save the character attribute }
XY := WhereXYAbs; { save the cursor position }
Cursor := CursorShape;
End;
CurrentScreen := NewScreen;
End;
Procedure DropWindow;
Var
OldScreen : ScreenPtr;
Begin
With CurrentScreen^ Do
Begin
If Previous = Nil Then ScreenSaved := False;
OldScreen := CurrentScreen; { release heap memory }
CurrentScreen := Previous;
Dispose(OldScreen);
End;
End;
Procedure RemoveWindow;
{ Restores screen memory, window coordinates, }
{ cursor position, and character attribute. }
Begin
If Not ScreenSaved Then Exit;
With CurrentScreen^ Do
Begin
If VideoMode = 7 { restore screen memory }
Then MonoScreen := Screen
Else ColorScreen := Screen;
WindMin := UpperCors; { restore the window coordinates }
WindMax := LowerCors;
TextAttr := OldAttr; { restore the character attribute }
GotoXYAbs(XY); { restore the cursor position }
SetCursor(Cursor);
DropWindow;
End;
End;
Procedure DuplicateChar(Character : Char;Count : Integer);
{ Uses the BIOS to write multiple copies of a character to the screen }
Begin
InLine($8A/$46/$06 { mov al,byte ptr char[bp] }
/$8B/$4E/$04 { mov cx,count[bp] }
/$B4/$09 { mov ah,09h }
/$8A/$1E/>TextAttr { mov bl,[TextAttr] }
/$32/$FF { xor bh,bh }
/$CD/$10 { int 10h }
);
End;
Procedure DrawBox(X1,Y1,X2,Y2,Forground,Background : Word;Border : BorderType);
{ Draws a double box around the window and reduces the window size. }
{ Inputs are the same as for MakeWindow. }
Type
BorderPart = (Top,Side,UpperLeft,UpperRight,LowerLeft,LowerRight);
Var
Loop : Integer;
Const
Borders : Array[Single..Solid,Top..LowerRight] of Char =
(('─','│','┌','┐','└','┘'), {single}
('═','║','╔','╗','╚','╝'), {double}
('═','│','╒','╕','╘','╛'), {combo }
('─','║','╓','╖','╙','╜'), {combo }
(' ',' ',' ',' ',' ',' '));{solid }
{ window type 0 has no border, type 5 uses the space character }
Begin
If VideoMode = 7 Then { Make sure the attributes can be }
Begin { seen on a monochrome screen. }
Forground := 7;
Background := 0;
End;
Window(X1,Y1,X2,Y2);
TextColor(Forground);
TextBackground(Background);
GotoXY(1,1);
If Border > None Then
Begin
Write(Borders[Border,UpperLeft]); { upper left }
DuplicateChar(Borders[Border,Top],Pred(X2-X1)); { top }
GotoXY(Succ(X2-X1),1);
Write(Borders[Border,UpperRight]); { upper right }
For Loop := 2 To Y2-Y1 Do
Begin
GotoXY(1,Loop);
Write(Borders[Border,Side]); { left side }
GotoXY(Succ(X2-X1),Loop);
Write(Borders[Border,Side]); { right side }
End;
Write(Borders[Border,LowerLeft]); { lower left }
DuplicateChar(Borders[Border,Top],Pred(X2-X1)); { bottom }
GotoXY(Succ(X2-X1),Succ(Y2-Y1));
DuplicateChar(Borders[Border,LowerRight],1); { lower right }
Window(Succ(X1),Succ(Y1),Pred(X2),Pred(Y2)); { reduce the window size }
End;
ClrScr;
End;
Procedure MakeWindow(X1,Y1,X2,Y2,Forground,BackGround : Word;
Border : BorderType);
{ Saves the screen and draws a box. }
{ Inputs are: The four window coordinates, }
{ the forground color, }
{ the background color, }
{ and the border type (see DrawBox) }
Begin
SaveScreen;
DrawBox(X1,Y1,X2,Y2,Forground,Background,Border);
End;
Begin
ScreenSaved := False;
End.